define('common:widget/ui/ai/afxPlayer/index', function(require, exports, module) {

  /**
   * @file afx播放器
   * @author wangxun10
   */
  
  var san = require('common:widget/ui/ai/san');
  
  return san.defineComponent({
      template: ''
          + '<div id="afxplayer" class="afx-content">'
          + '    <video'
          + '        s-if="isShow"'
          + '        s-ref="video"'
          + '        src="{{afxUrl}}"'
          + '        auto-rotate="{{false}}"'
          + '        autoplay'
          + '        playsinline'
          + '        x5-playsinline'
          + '        webkit-playsinline'
          + '        t7-video-player-type="inline"'
          + '        crossorigin="anonymous"'
          + '        style="display: none; width: 100%; position: absolute; z-index: -1;"'
          + '        loop="{{loop}}"'
          + '    >'
          + '    </video>'
          + '    <img'
          + '        src="{{bgUrl}}"'
          + '        class="canvas-bg"'
          + '        s-show="!canHideBgUrl && bgUrl"'
          + '    >'
          + '    <canvas'
          + '        s-ref="{{refName}}"'
          + '        class="gif-canvas"'
          + '    >'
          + '    </canvas>'
          + '</div>',
      initData: function () {
          return {
              afxUrl: '',
              bgUrl: '',
              // afx加载成功之后隐藏背景图，默认不隐藏
              hideBgUrl: false,
              isShow: false,
              hasPlay: false,
              shouldPlay: false, // 是否播放
              canHideBgUrl: false,
              loop: true,
              refName: 'canvas'
          };
      },
      attached: function () {
          if (!this.data.get('isShow') || !this.data.get('afxUrl')) {
              return;
          }
          var _this = this;
          this.nextTick(function () {
              _this.initVideo();
          });
  
          this.watch('shouldPlay', function (value) {
              var videoDom = this.ref('video');
              if (!videoDom) {
                  return;
              }
              if (!value) {
                  videoDom.pause();
                  this.data.set('canHideBgUrl', false);
                  videoDom.currentTime = 0;
              } else {
                  videoDom.play();
                  this.hideBg();
              }
          });
      },
      detached: function () {
          this.data.set('afxUrl', '');
          if (this.timer) {
              clearTimeout(this.timer);
          }
          var _this = this;
          // 避免在销毁时，gl先释放导致canvas出现白框
          setTimeout(function () {
              if (_this.gl) {
                  // Release WebGL context using the loseContext method
                  _this.gl.deleteBuffer(_this.buffer);
                  _this.gl.deleteTexture(_this.texture);
  
                  var loseContextExtension = _this.gl.getExtension('WEBGL_lose_context');
                  if (loseContextExtension) {
                      loseContextExtension.loseContext();
                  }
                  else {
                      _this.gl.bindBuffer(_this.gl.ARRAY_BUFFER, null);
                      _this.gl.bindTexture(_this.gl.TEXTURE_2D, null);
                  }
                  // 确保释放所有引用
                  _this.gl = null;
              }
          }, 50);
      },
      handlePlay: function () {
          var videoDom = this.ref('video');
          if (videoDom && videoDom.paused) {
              videoDom.play();
          }
      },
      initVideo: function () {
          var videoDom = this.ref('video');
          var _this = this;
          if (!videoDom) {
              return;
          }
          videoDom.muted = true;
          videoDom.pause();
          var shouldPlay = this.data.get('shouldPlay');
          videoDom.oncanplay = function () {
              if (!_this.data.get('hasPlay')) {
                  if (shouldPlay) {
                      videoDom.play();
                  }
                  _this.initAfx(videoDom);
                  _this.data.set('hasPlay', true);
              }
          };
          videoDom.oncanplaythrough = function () {
              if (!_this.data.get('hasPlay')) {
                  if (shouldPlay) {
                      videoDom.play();
                  }
                  _this.initAfx(videoDom);
                  _this.data.set('hasPlay', true);
              }
          };
          videoDom.onloadeddata = function () {
              if (!_this.data.get('hasPlay')) {
                  if (shouldPlay) {
                      videoDom.play();
                  }
                  _this.fire('canPlay');
                  _this.initAfx(videoDom);
                  _this.data.set('hasPlay', true);
              }
          };
      },
  
      initAfx: function (videoDom) {
          var vsCode = `attribute vec2 position;
          varying vec2 v_Texcoord;
          void main() {
              v_Texcoord = (position + 1.0) * 0.5;
              gl_Position = vec4(position, 0.0, 1.0);
          }`;
          var fsCode = `precision highp float;
          uniform sampler2D tex;
          varying vec2 v_Texcoord;
          void main() {
              // 取右边画面像素
              vec3 rgb = texture2D(tex, v_Texcoord * vec2(0.5, 1.0) + vec2(0.5, 0.0)).rgb;
              // 取左边画面像素
              float a = texture2D(tex, v_Texcoord * vec2(0.5, 1.0)).r;
              gl_FragColor = vec4(rgb, a);
          }`;
          var cavasDom = this.data.get('refName');
          var canvas = this.ref(cavasDom);
          if (!canvas) {
              return;
          }
          if (videoDom.videoWidth && videoDom.videoHeight) {
              canvas.width = videoDom.videoWidth / 2;
              canvas.height = videoDom.videoHeight;
          }
          var gl = canvas.getContext('webgl');
          if (!gl) {
              return;
          }
          gl.viewport(0, 0, canvas.width, canvas.height);
          gl.clearColor(0, 0, 0, 0);
          gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
          var posBuffer = this.createVertexBuffer(gl, [
              -1, -1,
              1, -1,
              -1, 1,
              1, 1
          ]);
          var program = this.createProgram(gl, vsCode, fsCode);
          gl.useProgram(program);
          this.setVertexBuffer(gl, program, 'position', posBuffer, 2);
          var videoTexture = this.createImageTexture(gl);
          var texLoc = gl.getUniformLocation(program, 'tex');
          gl.uniform1i(texLoc, 0);
          function update() {
              gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
              gl.bindTexture(gl.TEXTURE_2D, videoTexture);
              gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
              gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoDom);
              gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
              requestAnimationFrame(update);
          }
          requestAnimationFrame(update);
          this.gl = gl;
          this.buffer = posBuffer;
          this.texture = videoTexture;
  
          // 确定支持webgl再隐藏背景图
          this.data.get('shouldPlay') && this.hideBg();
      },
  
      hideBg: function () {
          // 判断是否支持webgl，不支持则不隐藏首帧默认图
          var cavasDom = this.data.get('refName');
          var canvas = this.ref(cavasDom);
          var _this = this;
          if (!canvas) {
              return;
          }
          // var gl = canvas.getContext('webgl');
          if (!this.gl) {
              return;
          }
          if (this.data.get('hideBgUrl')) {
              // 过200ms消失，防止闪一下
              this.timer = setTimeout(function () {
                  _this.data.set('canHideBgUrl', true);
              }, 200);
          }
      },
  
      createProgram: function (gl, vsCode, fsCode) {
          var vertexShader = gl.createShader(gl.VERTEX_SHADER);
          var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
          gl.shaderSource(vertexShader, vsCode);
          gl.shaderSource(fragmentShader, fsCode);
          gl.compileShader(vertexShader);
          gl.compileShader(fragmentShader);
          [vertexShader, fragmentShader].forEach(function (shader) {
              if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                  // console.log('Shader error:', gl.getShaderInfoLog(shader));
                  return null;
              }
          });
          var program = gl.createProgram();
          gl.attachShader(program, vertexShader);
          gl.attachShader(program, fragmentShader);
          gl.linkProgram(program);
          if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
              // console.log('Program link error');
          }
          return program;
      },
  
      setVertexBuffer: function (gl, program, symbol, buffer, itemSize) {
          gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
          var posLoc = gl.getAttribLocation(program, symbol);
          gl.enableVertexAttribArray(posLoc);
          gl.vertexAttribPointer(posLoc, itemSize, gl.FLOAT, false, 0, 0);
      },
  
      createVertexBuffer: function (gl, data) {
          var buffer = gl.createBuffer();
          if (data) {
              this.updateVertexBuffer(gl, buffer, data);
          }
          return buffer;
      },
  
      updateVertexBuffer: function (gl, buffer, data) {
          gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
          /* eslint-disable */
          if (data instanceof Array) {
              if (window.Float32Array) {
                  data = new Float32Array(data);
              }
          }
          /* eslint-disable */
          gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
      },
  
      createImageTexture: function(gl, img) {
          var tex = gl.createTexture();
          gl.bindTexture(gl.TEXTURE_2D, tex);
          // No mipmap
          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
          if (img) {
              gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
          }
          gl.bindTexture(gl.TEXTURE_2D, null);
  
          return tex;
      }
  });
  

});
